package com.qisimanxiang.dalaran.zuul.config;

import com.qisimanxiang.dalaran.zuul.custom.concurrent.ThreadSemaphore;
import com.qisimanxiang.dalaran.zuul.sentinel.DegradeStrategy;
import com.qisimanxiang.dalaran.zuul.sentinel.QpsStrategy;
import lombok.Data;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;

import javax.annotation.PostConstruct;
import java.util.Map;

/**
 * @author wangmeng
 * @date created in 9:57 上午 2019/9/16
 * @modified by
 */
@Data
@Slf4j
@ToString
@ConfigurationProperties(prefix = "sentinel")
public class SentinelClusterConfig {

    private static SentinelClusterConfig INSTANCE;

    private Integer instanceNum;

    private Integer globalDegradeRT;
    private Integer globalMaxDegradeTimeWindow;
    private Integer globalMinDegradeTimeWindow;
    private Integer globalDefaultQpsLimit;
    private Integer globalDefaultQueueingMs;
    private Integer serviceDefaultQpsLimit;
    private Integer serviceDefaultQueueingMs;
    private Integer customerDefaultQpsLimit;
    //线程数
    private Integer customerDefaultTcLimit;
    private Integer customerThreadQueueingMs;

    private Map<String, Integer> semaphoreMap;

    private Map<String, Integer> serviceLimit;

    private Map<String, Integer> customerServiceRtMap;

    private Map<String, Integer> customerServiceQpsLimit;

    public SentinelClusterConfig() {
        INSTANCE = this;
    }

    @PostConstruct
    public void init() {
        log.info("default config ：{}", this);
        QpsStrategy.flush(this);
        DegradeStrategy.flush(this);
        ThreadSemaphore.updateSemaphoreMap(semaphoreMap);
    }

    public static Integer getCustomerServiceRt(String apiPath, String customerId) {
        if (INSTANCE.getCustomerServiceRtMap() == null) {
            return null;
        }
        return INSTANCE.getCustomerServiceRtMap().get(apiPath + "::" + customerId);
    }

    public static Integer getTotalInstanceNum() {
        if (INSTANCE.instanceNum == null) {
            return 1;
        }
        return INSTANCE.instanceNum;
    }

}
